<?php

declare(strict_types=1);

namespace Phpben\Imi\ConfigCenter\Driver;

use RuntimeException;
use Imi\Config;
use Imi\Cache\CacheManager as Cache;
use Psr\SimpleCache\InvalidArgumentException;
use Yurun\Util\HttpRequest;
use Imi\Util\Random;

/**
 * 阿里云ACM驱动
 */
class AliyunMseNacos
{
    /**
     * 配置
     * @var array
     */
    protected array $config;

    public function __construct()
    {
        $this->config = Config::get('@app.beans.ConfigCenter.aliyun_mse_nacos');
        $this->client = new HttpRequest;
    }

    /**
     * 获取配置
     * @return array
     */
    public function get(): array
    {
        $response = $this->response([
            'Action' => 'GetNacosConfig',
        ]);
        $config = $response['Configuration']['Content'] ?? [];
        return is_array($config) ? $config : json_decode($config, true);
    }

    /**
     * 更新配置
     * @param array $content 配置内容
     */
    public function pull(array $content): void
    {
        $this->response([
            'Action' => 'UpdateNacosConfig',
            'Content' => json_encode($content, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
        ]);
    }

    protected function response(array $config): array
    {
        $url = reurl($this->config['endpoint']);
        $nonce = Random::letterAndNumber(18);
        $params = [
            'Version' => '2019-05-31',
            'Format' => "JSON",
            'AccessKeyId' => $this->config['access_key'],
            'SignatureMethod' => 'HMAC-SHA1',
            'Timestamp' => gmdate("Y-m-d\TH:i:s\Z"),
            'SignatureVersion' => '1.0',
            'InstanceId' => $this->config['instance_id'],
            'DataId' => $this->config['data_id'],
            'Group' => $this->config['group'],
            "NamespaceId" => $this->config['namespace'],
            'SignatureNonce' => $nonce,
        ];
        $params = array_merge($params, $config);
        ksort($params);
        $sign = '';
        foreach ($params as $k => $v) {
            $sign .= '&' . $this->percentEncode($k) . '=' . $this->percentEncode($v);
        }
        $params['Signature'] = base64_encode(hash_hmac('sha1', 'GET&%2F&' . $this->percentencode(substr($sign, 1)), $this->config['secret_key'] . '&', true));
        $response = $this->client->get($url, $params);
        $content = $response->getBody()->getContents();
        $json = json_decode($content, true);
        if (isset($json['Success']) && $json['Success'] === true) {
            return $json;
        }
        throw new RuntimeException($json['Message'] ?? "AliyunMseNacos http request faild");
    }

    protected function percentEncode($str): string
    {
        $res = urlencode($str);
        $res = preg_replace('/\+/', '%20', $res);
        $res = preg_replace('/\*/', '%2A', $res);
        $res = preg_replace('/%7E/', '~', $res);
        return $res;
    }

}